<template>
  <div class="rich-editor">
    <div :id="`editor-container${idName}`" class="editor-container"></div>
<!--    <upload style="display: none"-->
<!--            v-model:model-value="imgUrls"-->
<!--            list-type="picture-card"-->
<!--            ref="uploader"-->
<!--            :id="'richTextImgLoader_' + componentId"-->
<!--            :limit="0"-->
<!--            @success="handleImageUploadSuccess">-->
<!--      <template #default>-->
<!--        <el-button ref="hiddenUpload">click</el-button>-->
<!--      </template>-->
<!--    </upload>-->
    <input
        type="file"
        ref="uploader"
        multiple
        style="display: none"
        accept="image/png,image/jpg,image/jpeg"
        @input="handleImageUploadSuccess"/>
  </div>
</template>

<script lang="ts">
import Quill from 'quill'
import 'quill/dist/quill.snow.css'
// import upload from '@/components/upload.vue'
import {Ref} from "vue";
import {upload} from "@/utils/minio-upload";

export default defineComponent({
  // components: {
  //   upload
  // },

  props: {
    idName:{
      type:String,
      default:''
    },
    initialValue: String,
    scrollSelector: String, // 值为css选择器。使用光标插入html时，浏览器会滚动窗口并显示出光标位置，传入这个值冻结滚动
  },

  emits: ['change'],
  expose: ['insertText', 'insertHTML', 'clearEditor'],
  setup(props, context) {
    const initialValueRef = toRef(props, 'initialValue')

    const componentId = '' + new Date().getTime()
    const uploader:Ref<HTMLInputElement | undefined> = ref()
    const imgUrls = ref([])
    let quillInstance:Quill

    const handleImageToolClick = () => {
      uploader.value?.click()
    }

    const handleImageUploadSuccess = async (e: InputEvent) => {
      const inputTarget = e.target as HTMLInputElement
      const rss = await Promise.all([...(inputTarget.files ?? [])].map((file:File)=> upload(file, '/')))
      let i = 0
      while (i<rss.length) {
        const rsObj = rss[i] as {url: string, name: string}
        // 获取光标位置
        const pos = quillInstance?.getSelection()?.index ?? 0
        // 插入图片到光标位置
        quillInstance.insertEmbed(pos,'image', rsObj.url)
        // 移动光标到图片后
        quillInstance.setSelection(pos + 1 + i, 0)
        // 换行
        quillInstance.insertText(pos + 1 + i, '\n')

        i++
      }

      if (uploader.value) {
        uploader.value.value = ''
      }
    }

    const insertText = (text: string, index: number, source?: 'user') => {
      // 获取光标位置
      const pos = index ?? quillInstance?.getSelection()?.index ?? 0
      quillInstance.insertText(pos, text, source)
    }

    const insertHTML = (html: string, index?: number, source?: 'user') => {
      // 获取光标位置
      const pos = index ?? quillInstance?.getSelection()?.index ?? 0
      quillInstance.clipboard.dangerouslyPasteHTML(pos, html, source)
    }

    const clearEditor = () => {
      // 清空副文本数据
      quillInstance.deleteText(0, quillInstance.getLength())
    }

    const getHTML = () => {
      return quillInstance.root.innerHTML
    }

    let frozeScrollTop: number = 0
    let scrollElement: HTMLElement
    const freezeScroll = () => {
      if (props.scrollSelector) {
        scrollElement = <HTMLElement>document.querySelector(props.scrollSelector)
        if (scrollElement) {
          frozeScrollTop = scrollElement.scrollTop
        }
      }
    }

    const releaseScroll = () => {
      if (scrollElement) {
        scrollElement.scrollTop = frozeScrollTop
      }
    }

    // 插入初始值
    const insertInitialValue = (val: string | undefined) => {
      freezeScroll()
      quillInstance.deleteText(0, quillInstance.getLength())
      insertHTML(val || '')
      releaseScroll()
      quillInstance.blur()
    }

    watch(initialValueRef, (val: string | undefined) => {
      insertInitialValue(val)
    })

    const initQuill = () => {
      const toolbarOptions = [
        ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
        ['blockquote', 'code-block'],
        ['clean'],
        [{ 'header': 1 }, { 'header': 2 }],               // custom button values
        [{ 'list': 'ordered'}, { 'list': 'bullet' }],
        [{ 'script': 'sub'}, { 'script': 'super' }],      // superscript/subscript
        [{ 'indent': '-1'}, { 'indent': '+1' }],          // outdent/indent
        [{ 'direction': 'rtl' }],                         // text direction

        [{ 'size': ['small', false, 'large', 'huge'] }],  // custom dropdown
        [{ 'header': [1, 2, 3, 4, 5, 6, false] }],

        [{ 'color': [] }, { 'background': [] }],          // dropdown with defaults from theme
        [{ 'align': [] }],

        ['image'],                                    // remove formatting button
      ];
      
      quillInstance = new Quill(`#editor-container${props.idName}`, {
        modules: {
          toolbar: {
            container: toolbarOptions,
            handlers: {
              image(value: any) {
                handleImageToolClick()
                return false
              }
            }
          }
        },
        placeholder: '点击编辑...',
        theme: 'snow'
      })

      quillInstance.on('text-change', (delta, oldDelta, source) => {
        context.emit('change', {delta, oldDelta, source, innerHTML: quillInstance.root.innerHTML, quillInstance})
      })
    }

    onMounted(() => {
      initQuill()
    })

    return {
      componentId,
      uploader,
      imgUrls,
      // editorValue,
      insertText,
      insertHTML,
      getHTML,
      handleImageUploadSuccess,
      clearEditor,
    }
  },
})
</script>

<style>
.el-form-item__content {
  line-height: unset;
}
</style>

<style scoped lang="scss">
.editor-container {
  width: 100%;
  height: 375px;

  >img {
    max-width: 100%;
  }
}
</style>
